package lelouet.sh3d.plugins.sweetDatacenter.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Queue;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

import lelouet.sh3d.plugins.sweetDatacenter.SweetDatacenterPlugin;
import lelouet.sh3d.plugins.sweetDatacenter.gui.SelectedElementPane.MControler;
import lelouet.sh3d.plugins.sweetDatacenter.model.GRack;
import lelouet.sh3d.plugins.sweetDatacenter.model.GServer;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
 * Builder, which is free for non-commercial use. If Jigloo is being used
 * commercially (ie, by a corporation, company or business for any purpose
 * whatever) then you should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details. Use of Jigloo implies
 * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
 * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
 * ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class RackPropertiesPanel extends JPanel implements ActionListener {

	protected static final int FIELD_WIDTH = 170;
	protected static final int LABEL_WIDTH = 120;
	protected static final int ROW_HEIGHT = 20;

	private static final long serialVersionUID = 1L;

	/** the controller to report modifications on */
	protected MControler controler;

	private JPanel rackInfosPanel;
	private JPanel serversPositionsPanel;
	protected ATextFieldValidation modifSize;
	protected ATextFieldValidation renameRack;

	protected JButton renameButton;

	public RackPropertiesPanel() {
		initGUI();
	}

	/**
	 * a panel to describe a {@link GServer} in a rack, to be put in the panel
	 * of the rack
	 */
	@SuppressWarnings("serial")
	protected class ServerLevel extends JPanel {

		/** the height of each U level for each server. */
		protected static final int VERTICAL_PIXELS_PER_U = 15;

		/** the pixels the label for server descriptions should have the width */
		protected static final int SERVERDESC_PIXEL_WIDTH = 100;

		protected JButton serverDescbutton = new JButton();
		protected JButton buttonUp = new JButton("/\\");
		protected JButton buttonDown = new JButton("\\/");
		protected GServer describedServer;
		protected int serverLevel;

		/**
		 * create {@link ServerLevel} showing informations on a given server,
		 * placed on a given level
		 */
		public ServerLevel(GServer server, int level) {
			// setBorder(BorderFactory.createLineBorder(Color.black));
			setLayout(new BorderLayout());
			serverDescbutton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if (describedServer != null) {
						controler.setSelectedServer(describedServer);
					}
				}
			});
			add(serverDescbutton, BorderLayout.CENTER);
			serverDescbutton.setPreferredSize(new Dimension(
					SERVERDESC_PIXEL_WIDTH, VERTICAL_PIXELS_PER_U));
			JPanel panForButton = new JPanel(new GridLayout(1, 2));
			panForButton.add(buttonUp);
			panForButton.add(buttonDown);
			add(panForButton, BorderLayout.EAST);
			buttonUp.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					controler.moveGServerUp(serverLevel);
				}
			});
			buttonDown.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					controler.moveGServerDown(serverLevel);
				}
			});
			reinit(server, level);
		}

		public void reinit(GServer server, int level) {
			int heightU = 1;
			if (server != null) {
				heightU = server.getVSize();
				serverDescbutton.setText(server.getName());
			} else {
				serverDescbutton.setText("");
			}
			setPreferredSize(new Dimension(SERVERDESC_PIXEL_WIDTH, heightU
					* VERTICAL_PIXELS_PER_U));
			describedServer = server;
			serverLevel = level;
		}

	}

	/**
	 * a pool of available ServerLevel we already used, not to create/delete too
	 * many objects
	 */
	protected Queue<ServerLevel> availablepanels = new LinkedList<ServerLevel>();

	protected ServerLevel newServerLevel(GServer server, int level) {
		if (availablepanels.isEmpty()) {
			return new ServerLevel(server, level);
		} else {
			ServerLevel ret = availablepanels.remove();
			ret.reinit(server, level);
			return ret;
		}
	}

	public void updateRack(GRack toShow) {
		modifSize.setText(Integer.toString(toShow.getLvlNb()));
		renameRack.setText(toShow.getName());
		for (Component comp : serversPositionsPanel.getComponents()) {
			ServerLevel sl = (ServerLevel) comp;
			availablepanels.add(sl);
		}
		serversPositionsPanel.removeAll();
		for (int i = toShow.getLvlNb() - 1; i >= 0; i--) {
			GServer serv = toShow.serverAtLvl(i);
			if (serv != null) {
				// we put the server on the lowest level it is
				i = i - serv.getVSize() + 1;
			}
			serversPositionsPanel.add(newServerLevel(serv, i));
		}
	}

	protected void setControler(MControler controler) {
		this.controler = controler;
	}

	private void initGUI() {
		setSize(SweetDatacenterPlugin.UTILS_FRAME_DIMENSION);
		BorderLayout thisLayout = new BorderLayout();
		setLayout(thisLayout);
		{
			rackInfosPanel = new JPanel();
			GridLayout rackInfosPanelLayout = new GridLayout(0, 1);
			this.add(rackInfosPanel, BorderLayout.NORTH);
			rackInfosPanel.setLayout(rackInfosPanelLayout);
			{
				modifSize = new ATextFieldValidation("size in U", FIELD_WIDTH,
						LABEL_WIDTH, ROW_HEIGHT) {

					private static final long serialVersionUID = 1L;

					@Override
					public void onValidation(String text) {
						controler.setRackSize(text);
					}
				};
				rackInfosPanel.add(modifSize);
				renameRack = new ATextFieldValidation("change name",
						LABEL_WIDTH, FIELD_WIDTH, ROW_HEIGHT) {

					private static final long serialVersionUID = 1L;

					@Override
					public void onValidation(String text) {
						controler.setRackName(text);
					}
				};
				rackInfosPanel.add(renameRack);
				renameButton = new JButton("rename servers");
				renameButton.addActionListener(this);
				rackInfosPanel.add(renameButton);
			}
		}
		{
			serversPositionsPanel = new JPanel();
			BoxLayout serversPositionPanelLayout = new BoxLayout(
					serversPositionsPanel, BoxLayout.Y_AXIS);
			serversPositionsPanel.setLayout(serversPositionPanelLayout);
			this.add(serversPositionsPanel, BorderLayout.CENTER);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == renameButton) {
			controler.renameRackServers();
		}
	}
}
